#include "double_link_list.h"

// 双向链表的创建
int init_double_link_list(Double_Link_List **list)
{
    *list = (Double_Link_List *)malloc(sizeof(Double_Link_List));
    if (NULL == list)
    {
        ERRLOG("创建空间失败");
        // return EOF;      // 返回 退出当前函数
        exit(EOF); // 退出当前进程
    }

    (*list)->next = NULL;

    return 0;
}

// 双向链表的插入
int insert_double_link_list(Double_Link_List *list, Elenemt_data data, int pos)
{
    if (NULL == list)
    {
        ERRLOG("头节点 为 NULL");
        return 0;
    }

    // 创建新结点 并为新结点写入数据
    Double_Node *new_node = (Double_Node *)malloc(sizeof(Double_Node));
    if (NULL == new_node)
    {
        ERRLOG("结点创建失败");
        return EOF;
    }

    new_node->data = data;
    new_node->next = new_node;
    new_node->prev = new_node;

    // 头插
    if (1 == pos || NULL == list->next)
    {
        // 链表中 无结点的头插
        if (NULL == list->next)
        {
            list->next = new_node;
            return 0;
        }
        // 有结点的头插
        new_node->prev = list->next->prev;

        new_node->next = list->next;

        list->next->prev->next = new_node;

        list->next->prev = new_node;

        list->next = new_node;

        return 0;
    }

    // 任意位置插入

    Double_Node *ptr_node = list->next;

    for (size_t i = 1; i < pos - 1 && list->next != ptr_node->next; i++)
    {
        ptr_node = ptr_node->next;
    }

    // 开始插入
    new_node->next = ptr_node->next;

    new_node->prev = ptr_node;

    ptr_node->next->prev = new_node;
    
    ptr_node->next = new_node;

    return 0;
}

// 双向链表的删除
int delete_double_link_list(Double_Link_List *list, int pos)
{
    if (NULL == list || NULL == list->next)
    {
        ERRLOG("头节点 为 NULL");
        return 0;
    }

    // 头删   当要删除的位置为1 时  当删除的链表只有一个元素
    if (1 == pos || NULL == list->next->next)
    {
        // 链表只有一个结点的头删
        if (NULL == list->next->next)
        {
            free(list->next);
            list->next = NULL;
            return 0;
        }
        // 多个数据的头删
        Double_Node *ptr_node = list->next;
        //两种都可以
        ptr_node->next->prev = ptr_node->prev;
        ptr_node->prev->next = ptr_node->next;
        list->next = ptr_node->next;
        //list->next = ptr_node->next;
        //ptr_node->prev->next = list->next;
        //list->next->prev = ptr_node->prev;

        // 释放
        free(ptr_node);

        return 0;
    }

    // 任意位置删
    Double_Node *ptr_node_1 = list->next;
    Double_Node *ptr_node_2 = ptr_node_1->next;

    for (size_t i = 1; i < pos - 1 && list->next != ptr_node_1->next->next; i++)
    {
        ptr_node_1 = ptr_node_1->next;
    }

    ptr_node_2 = ptr_node_1->next;

    //开始删除(中间删和尾删)
    ptr_node_1->next = ptr_node_2->next;

    ptr_node_2->next->prev = ptr_node_1;
    

    // 释放
    free(ptr_node_2);

    return 0;
}

// 双向链表的查找
Double_Node* find_name_double_link_list(Double_Link_List* list, char* name)
{
    if (NULL == list || NULL == list->next)
    {
        ERRLOG("链表为 NULL 或者 链表内无数据");
        return NULL;
    }
    // 查找名字
    if (0 == strlen(name))
    {
        printf("请输入要查找的名字:");
        scanf("%s" , name);
    }
    Double_Node * ptr_node = list->next;
    do
    {
        if (strcmp(ptr_node->data.name,name)==0)
        {
            return ptr_node;
        }
        ptr_node = ptr_node->next;
        
    } while (ptr_node != list->next);
    return NULL;
}

// 双向链表的修改
int up_data_name_double_link_list(Double_Link_List*list,Double_Node * node)
{
    if (NULL == list || NULL == list->next)
    {
        ERRLOG("链表为 NULL 或者 链表内无数据");
        return EOF;
    }
    // 打印原始数据

    printf("姓名\t性别\t年纪\t学号\t成绩\n");

    printf("%s\t%s\t%d\t%d\t%d\n",\
        node->data.name , node->data.sex , node->data.age ,\
        node->data.id , node->data.sco);

    // 修改
    int num=0; // 记录用户的输入

    // 开始修改
    while (num != 6)
    {
        printf("1、姓名 2、性别 3、年纪 4、学号 5、成绩 6、退出");
        printf("请输入你要修改的选项:\n");
        scanf("%d", &num);

        switch (num)
        {
        case 1:
            printf("请输入姓名:");
            scanf("%s", node->data.name);
            break;
        case 2:
            printf("请输入性别:");
            scanf("%s", node->data.sex);
            break;
        case 3:
            printf("请输入年纪:");
            scanf("%d", &node->data.age);
            break;
        case 4:
            printf("请输入学号:");
            scanf("%d", &node->data.id);
            break;
        case 5:
            printf("请输入成绩:");
            scanf("%d", &node->data.sco);
            break;
        case 6:
            printf("退出");
            break;
        default:
            break;
        }
    }
    
    return 0;
}

// 双向链表的遍历
int print_double_link_list(Double_Link_List *list)
{
    if (NULL == list || NULL == list->next)
    {
        ERRLOG("链表为 NULL 或者 链表内无数据");
        return EOF;
    }

    Double_Node *ptr_node = list->next;

    printf("姓名\t性别\t年纪\t学号\t成绩\n");

    do
    {
        printf("%s\t%s\t%d\t%d\t%d\n",
               ptr_node->data.name, ptr_node->data.sex, ptr_node->data.age,
               ptr_node->data.id, ptr_node->data.sco);
        ptr_node = ptr_node->next;
    } while (list->next != ptr_node);

    return 0;
}

// 双向链表的判空
int Is_Empty_double_link_list(Double_Link_List* list)
{
    if (NULL == list)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }

    if (NULL == list->next)
    {
        return EOF;
    }
    return 0;
}

// 双向链表的清空
int Clear_double_link_list(Double_Link_List* list)
{
    if (NULL == list || NULL == list->next)
    {
        ERRLOG("头节点 为 NULL 或者链表内无数据")
        return EOF;
    }
    Double_Node* ptr_node_1 = list->next;
    Double_Node* ptr_node_2 = ptr_node_1->next;
    do
    {
        free(ptr_node_1);
        // 移动指针
        ptr_node_1 = ptr_node_2;
        
        ptr_node_2 = ptr_node_2->next;
    } while (list->next != ptr_node_1);
    list->next = NULL;
    return 0;
}

// 双向链表的合并
int merge_double_link_lists(Double_Link_List* list1, Double_Link_List* list2)
{
    if (NULL == list1 || NULL == list2)
    {
        ERRLOG("传入的头结点 为 NULL");
        return EOF;
    }
    // list2.next 不能为空
    if (NULL == list2->next)
    {
        ERRLOG("list2 无数据");
        return EOF;
    }
    //寻找表1和表2的尾节点
    Double_Node* ptr_node_1 = list1->next->prev;
    Double_Node* ptr_node_2 = list2->next->prev;
    //将表2的头节点连接再表1的尾节点后
    ptr_node_1->prev->next = list2;
    //list2->next->prev = ptr_node_1;
    ptr_node_2->prev->next = ptr_node_1->prev;
    list1->next->prev = ptr_node_2->prev;
    //Double_Link_List*list = ptr_node_1;
    //insert_double_link_list();
    free(ptr_node_2);
    return 0;
}

// 双向链表的销毁
int free_double_link_list(Double_Link_List **list)
{
    if (NULL == *list)
    {
        ERRLOG("链表为 NULL");
        return EOF;
    }

    // 销毁链表内的结点

    Double_Node *ptr_node_1 = (*list)->next;
    Double_Node *ptr_node_2 = ptr_node_1->next;

    // 销毁结点
    do
    {
        //printf("销毁成功 %s\n" ,ptr_node_1->data.name);
        free(ptr_node_1);
        // 移动指针
        ptr_node_1 = ptr_node_2;
        
        ptr_node_2 = ptr_node_2->next;

    } while ((*list)->next != ptr_node_1);

    // 销毁头结点
    free(*list);
    *list = NULL;

    return 0;
}